package org.android.bbdroid;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.android.bbdroid.gui.BBDroidForumAdapter;
import org.android.bbdroid.guiutils.Alerts;
import org.android.bbdroid.guiutils.HTMLUtils;
import org.android.bbdroid.webservice.PHPBBClient;
import org.android.bbdroid.webservice.data.CategoryForum;
import org.android.bbdroid.webservice.data.Forum;
import org.android.bbdroid.webservice.data.TopicForum;
import org.android.bbdroid.webservice.data.TopicInfo;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

public class BBDroidForumActivity extends Activity {
	private Forum next = null;

	private List<List<Map<String, Object>>> getChildData(List<Forum> forums,
			Iterator<TopicInfo> topics) {

		List<List<Map<String, Object>>> childData = new LinkedList<List<Map<String, Object>>>();
		List<Map<String, Object>> noCategoryForums = new LinkedList<Map<String, Object>>();

		for (Forum f : forums) {

			// category forums
			if (f instanceof CategoryForum) {
				CategoryForum c = (CategoryForum) f;
				List<Map<String, Object>> list = new LinkedList<Map<String, Object>>();

				for (Forum subforum : c) {
					Map<String, Object> map = new HashMap<String, Object>();
					setForum(map, subforum.getName(),
							subforum.getDescription(), subforum);
					list.add(map);
				}
				childData.add(list);

			} else { // no category forums
				Map<String, Object> map = new HashMap<String, Object>();
				setForum(map, f.getName(), f.getDescription(), f);
				noCategoryForums.add(map);
			}
		}

		childData.add(noCategoryForums);
		if (topics != null) {
			List<Map<String, Object>> topicsList = new LinkedList<Map<String, Object>>();
			while (topics.hasNext()) {
				TopicInfo tf = topics.next();
				Map<String, Object> map = new HashMap<String, Object>();
				setForum(map, tf.getTitle(), "", tf);
				topicsList.add(map);
			}
			childData.add(topicsList);
		}
		return childData;
	}

	private List<Map<String, Object>> getGroupData(List<Forum> forums,
			boolean isTopicForum) {
		List<Map<String, Object>> categories = new LinkedList<Map<String, Object>>();
		for (Forum f : forums) {
			if (f instanceof CategoryForum) {
				Map<String, Object> map = new HashMap<String, Object>();
				setCategory(map, f.getName(), f.getDescription(),
						(CategoryForum) f);
				categories.add(map);
			}
		}
		Map<String, Object> map = new HashMap<String, Object>();
		setCategory(map,
				getString(org.android.bbdroid.R.string.no_category_text), "",
				null);
		categories.add(map);

		if (isTopicForum) {
			map = new HashMap<String, Object>();
			setCategory(
					map,
					getString(org.android.bbdroid.R.string.topic_category_text),
					"", null);
			categories.add(map);
		}

		return categories;
	}

	private void setCategory(Map<String, Object> paramMap, String category,
			String desc, CategoryForum data) {
		paramMap.put("category", category);
		paramMap.put("category_desc", desc);
		paramMap.put("category_data", data);
	}

	private void setForum(Map<String, Object> paramMap, String name,
			String description, Object data) {
		paramMap.put("name", name);
		paramMap.put("description", description);
		paramMap.put("data", data);
	}

	private void setup() {
		
		final ProgressDialog dlg=Alerts.prog(this, "", getString(org.android.bbdroid.R.string.loading_text), true);
		new AsyncTask<Forum,Void,List<Forum>>(){
			@Override
			protected List<Forum> doInBackground(Forum... params) {
				PHPBBClient client = PHPBBClient.getInstance();
				List<Forum> forums = null;

				if (params[0] == null) { // root forum
					forums = client.getForums();
				} else { // inner forum
					forums = client.getForums(params[0]);
				}
				return forums;
			}
			
			@Override
			protected void onPostExecute(List<Forum> forums){
				dlg.dismiss();
				if(forums==null){
					Alerts.w(BBDroidForumActivity.this, 
							org.android.bbdroid.R.string.network_error_text, 
							org.android.bbdroid.R.string.cannot_connect_text);
					return;
				}
				PHPBBClient.SiteInfo info = PHPBBClient.getInstance().getSiteInfo();
				if(next==null) //root forum
					setTitle(HTMLUtils.fromHTML(info.getSiteName() + " ("
							+ info.getSiteDescription() + ")"));
				else
					setTitle(HTMLUtils.fromHTML(next.getName()));
				
				ListView lv = (ListView) findViewById(org.android.bbdroid.R.id.forumListView);
				List<Map<String, Object>> groupData = getGroupData(forums, next != null
						&& next instanceof TopicForum);
				List<List<Map<String, Object>>> childData = getChildData(
						forums,
						(next != null && next instanceof TopicForum) ? ((TopicForum) next)
								.topicsIterator() : null);
				lv.setAdapter(new BBDroidForumAdapter(getApplicationContext(), groupData, "category",
						"category_desc", childData, "name", "description"));
			}
			
		}
		.execute(next);
	}
	

	@Override
	public void onBackPressed() {
		if (isTaskRoot()){
			Alerts.yesno(this, org.android.bbdroid.R.string.exit_text,
					org.android.bbdroid.R.string.want_exit_question_text,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface di, int which) {
							if (which == DialogInterface.BUTTON_POSITIVE){
								new AsyncTask<Void,Void,Void>(){

									@Override
									protected Void doInBackground(Void... params) {
										PHPBBClient.getInstance().logout();
										return null;
									}
									
								}
								.execute();
								BBDroidForumActivity.super.onBackPressed();
							}
						}
					});
		}else
			super.onBackPressed();
	}

	@Override
	protected void onCreate(Bundle b) {
		super.onCreate(b);
		setContentView(org.android.bbdroid.R.layout.forums);
		ListView lv = (ListView) findViewById(org.android.bbdroid.R.id.forumListView);
		Bundle bundle = getIntent().getExtras();
		if (bundle != null)
			this.next = ((Forum) bundle.getSerializable("next"));
		setup();
		lv.setOnItemClickListener(new ChildListener());
	}

	@Override
	protected void onRestart(){
		super.onRestart();
		setup();
	}
	
	@Override
	public Dialog onCreateDialog(int paramInt, Bundle paramBundle) {
		return Alerts.onCreateDialog(this, paramInt, paramBundle);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu paramMenu) {
		getMenuInflater().inflate(org.android.bbdroid.R.menu.main_menu,
				paramMenu);
		MenuItem item = paramMenu
				.findItem(org.android.bbdroid.R.id.add_topic_menu);
		if ((this.next == null) || (!(this.next instanceof TopicForum))) {
			item.setVisible(false);
			item.setEnabled(false);
		}
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case org.android.bbdroid.R.id.logout_menu:
			final ProgressDialog dlg=Alerts.prog(this, "", 
					getString(org.android.bbdroid.R.string.loading_text), true);
			
			new AsyncTask<Void, Void, Void>(){

				@Override
				protected Void doInBackground(Void... params) {
					PHPBBClient.getInstance().logout();
					return null;
				}
				@Override
				protected void onPostExecute(Void result){
					dlg.dismiss();
					finish();
					startActivity(new Intent(BBDroidForumActivity.this, BBDroidLoginActivity.class));
				}
			}
			.execute();
			
			
			return true;
		case org.android.bbdroid.R.id.add_topic_menu:
			TopicForum topicForum = (TopicForum) this.next;
			if (!topicForum.isAuthPost()) {
				Alerts.w(this,
						org.android.bbdroid.R.string.not_authorized_text,
						org.android.bbdroid.R.string.not_authorized_topic_text);
				return true;
			}

			Intent i = new Intent(this, BBDroidSubmitPostTopicActivity.class);
			i.setAction(BBDroidActions.ADD_TOPIC);
			Bundle b = new Bundle();
			b.putSerializable("forum", topicForum);
			i.putExtras(b);
			startActivity(i);
			return true;
		case org.android.bbdroid.R.id.update_main_menu:
			finish();
			startActivity(getIntent());
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}

	}

	private class ChildListener implements AdapterView.OnItemClickListener {
		private ChildListener() {
		}

		public void onItemClick(AdapterView<?> paramAdapterView, View v,
				int position, long id) {
			
			@SuppressWarnings("unchecked")
			Map<String, Object> data = (Map<String, Object>) paramAdapterView
					.getItemAtPosition(position);

			if (data.containsKey("category_data"))
				return;

			Object childData = data.get("data");

			if (childData instanceof TopicInfo) {
				Intent i = new Intent(BBDroidForumActivity.this,
						BBDroidTopicActivity.class);
				Bundle b = new Bundle();
				b.putSerializable("topic", (Serializable) childData);
				i.putExtras(b);
				startActivity(i);
			} else {
				Intent i = new Intent(BBDroidForumActivity.this,
						BBDroidForumActivity.class);
				Bundle b = new Bundle();
				b.putSerializable("next", (Serializable) childData);
				i.putExtras(b);
				startActivity(i);
			}
		}
	}
}
